package system.track;

import system.train.Train;
import java.util.LinkedList;
import system.communication.Monitor;
import system.ui.Engine;

/**
 * This class represents a sensor in memory.
 *
 * Behaviorally, a sensor will recieve notification via
 * tripped() from the SensorNotifier then will in turn 
 * notify any trains registered of the message.
 * 
 * @author David Kolb
 */
public class Sensor
{
    private int id;
    private LinkedList<Train> trains;

    public Sensor()
    {
        trains = new LinkedList<Train>();
    }

    public Sensor(int id)
    {
        this();
        setID(id);
    }

    /**
     * Registers an integer ID with the the sensor.
     *  
     * @param id the ID number of the sensor from the track map
     */
    public void setID(int id)
    {
        this.id = id;
        Monitor.getInstance().registerSensor(this);
    }

    /**
     * Retrieves the ID number of the sensor.
     * 
     * @return an ID number that matches the nubmer of a sensor on the map.
     */
    public int getID()
    {
        return id;
    }

    /**
     * This registers a train to recieve notification calls when the sensor
     * is tripped.
     *
     * @param t a reference to the train object to register.
     */
    public synchronized void registerForNotification(Train t)
    {
        System.out.println("Sensor " + this.id + " has been registered");
        trains.add(t);
    }

    /**
     * This removes a train from the sensors internal data structure of trains
     * to notify when it is tripped.
     * @param t a reference to the train to remove from notification.
     */
    public synchronized void unregisterForNotification(Train t)
    {
        System.out.println("Sensor " + this.id + " has been unregistered");
        trains.remove(t);
    }

    /**
     * This function is called when a sensor is tripped.
     *
     * The major effect of this is that the sensor will notify
     * any trains registered to it.
     */
    public synchronized void tripped()
    {
        System.out.println("Sensor " + this.id + " has been tripped");
        while(trains.size() > 0)
        {
            Train aTrain = trains.getFirst();
            aTrain.tripSensor();
            unregisterForNotification(aTrain);
        }
        Engine.getInstance().postTripSensor(id);
    }

}
